﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EyFramework.SocketServer.InData;
using EyFramework.SocketServer.OutData;
using EyFramework.SocketServer.Utils;
using Newtonsoft.Json;
using WebSocketSharp;
using WebSocketSharp.Server;

namespace EyFramework.SocketServer.Behavior
{
    /**
     * 远程控制的服务
     */

    public class RemoteBehavior : BaseBehavior
    {
        public enum RemoteControlType
        {
            RemoteDesktop = 1,
            Vnc = 2,
            Radmin = 3
        }

        public enum RemoteMethod
        {
            RemoteControl = 1,
            CheckRemoteService = 2
        }

        private IniFileUtil iniFileUtil = new IniFileUtil(Path.Combine(DirectoryUtil.AssemblyDirectory(), "SocketConfig.ini"));

        public override string doBusiness(string inData)
        {
            var outData = "";
            RemoteInData remoteInData = JsonConvert.DeserializeObject<RemoteInData>(inData);
            switch ((RemoteMethod)remoteInData.RemoteMethod)
            {
                case RemoteMethod.RemoteControl:
                    RemoteControl(remoteInData);
                    break;

                case RemoteMethod.CheckRemoteService:
                    CheckRemoteService(remoteInData);
                    break;

                default:
                    throw new Exception("未实现的方法！，请确定参数是否错误！");
            }
            return ReturnResult.Success(outData);
        }

        protected override void OnMessage(MessageEventArgs e)
        {
            string inData = e.Data;
            try
            {
                RemoteInData remoteInData = JsonConvert.DeserializeObject<RemoteInData>(inData);
                switch ((RemoteMethod)remoteInData.RemoteMethod)
                {
                    case RemoteMethod.RemoteControl:
                        RemoteControl(remoteInData);
                        break;

                    case RemoteMethod.CheckRemoteService:
                        CheckRemoteService(remoteInData);
                        break;

                    default:
                        Send(JsonConvert.SerializeObject(ReturnResult.Fail(remoteInData.MessageId, "未实现的方法！，请确定参数是否错误！")));
                        break;
                }
            }
            catch (Exception ex)
            {
                Send(ReturnResult.Fail(ex.Message, ex));
            }
        }

        /**
         * 检测远程服务是否在线
         */

        private void CheckRemoteService(RemoteInData remoteInData)
        {
            StringBuilder remoteState = new StringBuilder();
            string[] remoteTypes = remoteInData.RemoteType.Split(',');
            foreach (string remoteControlType in remoteTypes)
            {
                var isconnect = false;
                switch ((RemoteControlType)int.Parse(remoteControlType))
                {
                    case RemoteControlType.RemoteDesktop:
                        isconnect = NetUitl.CheckPortEnable(remoteInData.Ip, 3389);
                        break;

                    case RemoteControlType.Vnc:
                        isconnect = NetUitl.CheckPortEnable(remoteInData.Ip, 5900);
                        break;

                    case RemoteControlType.Radmin:
                        isconnect = NetUitl.CheckPortEnable(remoteInData.Ip, 4899);
                        break;
                }
                if (isconnect)
                {
                    remoteState.Append(remoteState.Length > 0 ? "," : "").Append(remoteControlType);
                }
            }
            string returnStr = JsonConvert.SerializeObject(ReturnResult.Success(remoteState.ToString()));
            Send(returnStr);
        }

        private void RemoteControl(RemoteInData remoteInData)
        {
            string vncexe = Path.Combine(DirectoryUtil.AssemblyDirectory(), iniFileUtil.IniReadValue("SocketServer", "vnc", "vnc.exe"));
            string radminexe = Path.Combine(DirectoryUtil.AssemblyDirectory(), iniFileUtil.IniReadValue("SocketServer", "radmin", "radmin.exe"));
            int remoteType = int.Parse(remoteInData.RemoteType);
            switch ((RemoteControlType)remoteType)
            {
                case RemoteControlType.RemoteDesktop:

                    #region 执行远程桌面

                    Process p = new Process();
                    //设置要启动的应用程序
                    p.StartInfo.FileName = "cmd.exe";
                    //是否使用操作系统shell启动
                    p.StartInfo.UseShellExecute = false;
                    // 接受来自调用程序的输入信息
                    p.StartInfo.RedirectStandardInput = true;
                    //输出信息
                    p.StartInfo.RedirectStandardOutput = true;
                    // 输出错误
                    p.StartInfo.RedirectStandardError = true;
                    //不显示程序窗口
                    p.StartInfo.CreateNoWindow = true;
                    //启动程序
                    p.Start();
                    string strInput = string.Format("mstsc /v:{0} /admin /f", remoteInData.Ip);
                    //向cmd窗口发送输入信息
                    p.StandardInput.WriteLine(strInput + "&exit");
                    p.StandardInput.AutoFlush = true;
                    //获取输出信息
                    p.StandardOutput.ReadToEnd();
                    //等待程序执行完退出进程
                    p.WaitForExit();
                    p.Close();

                    #endregion 执行远程桌面

                    break;

                case RemoteControlType.Vnc:
                    Process.Start(vncexe, remoteInData.Ip); //打开程序B
                    break;

                case RemoteControlType.Radmin:
                    Process.Start(radminexe, string.Format("/connect:{0}", remoteInData.Ip)); //打开程序B
                    break;
            }
            Send(JsonConvert.SerializeObject(ReturnResult.Success(remoteInData.MessageId)));
        }
    }
}